package com.recSys.dataProcessing;

import java.util.HashMap;

/**
 * Created by dell on 2018/1/25.
 */
public class CosineSimilarity {
    /**
     * Method to calculate cosine similarity between two vector.
     * @param vector1 : vector 1 (a)
     * @param vector2 : vector 2 (b)
     * @return
     */
    public static double cosineSimilarity(double[] vector1, double[] vector2) {
        double dotProduct = 0.0;
        double magnitude1 = 0.0;
        double magnitude2 = 0.0;
        double cosineSimilarity = 0.0;

        for (int i = 0; i < vector1.length; i++) //vector1 and vector2 must be of same length
        {
            dotProduct += vector1[i] * vector2[i];  //a.b
            magnitude1 += Math.pow(vector1[i], 2);  //(a^2)
            magnitude2 += Math.pow(vector2[i], 2); //(b^2)
        }

        magnitude1 = Math.sqrt(magnitude1);//sqrt(a^2)
        magnitude2 = Math.sqrt(magnitude2);//sqrt(b^2)

        if (magnitude1 != 0.0 | magnitude2 != 0.0) {
            cosineSimilarity = dotProduct / (magnitude1 * magnitude2);
        } else {
            return 0.0;
        }
        return cosineSimilarity;
    }

    /**
     * 稀疏数据 相似度计算
     * @param a
     * @param b
     * @return
     */
    public static Double evaluate(String a, String b) {
        if(a==null || b==null)
            return 0.0;
        String temp1[]=a.split(" ");
        String temp2[]=b.split(" ");
        if (temp1==null || temp2==null) {
            return 0.0;
        }
        HashMap<String, Double> map1=new HashMap<String, Double>();
        HashMap<String, Double> map2=new HashMap<String, Double>();
        for(String temp:temp1)
        {
            String t[]=temp.split(":");
            map1.put(t[0], Double.parseDouble(t[1]));
        }
        for(String temp:temp2)
        {
            String t[]=temp.split(":");
            map2.put(t[0], Double.parseDouble(t[1]));
        }
        double fenzi=0;
        double fenmu1=0;
        for(String i:map1.keySet())
        {
            double value=map1.get(i);
            if (map2.get(i)!=null) {
                fenzi+=value*map2.get(i);
            }
            fenmu1+=value*value;
        }
        double fenmu2=0;
        for(double i:map2.values())
        {
            fenmu2+=i*i;
        }
        double fenmu=Math.sqrt(fenmu1)*Math.sqrt(fenmu2);
        return fenzi/fenmu;
    }

    public static void main(String[] args) {
//        String a="0:1.0,1:3.0,2:0";
//        String b="0:0,1:2.5,2:1.9";
//        System.out.println(evaluate(a,b));
        double[] vector1 = {1,1,0,0.25,1,0};
        double[] vector2 = {1,1,1,0.65,0,0};
        System.out.println(cosineSimilarity(vector1,vector2));
    }
}
